package com.dwin.h5.app.ui.pages;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.AnimationDrawable;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.dwin.h5.app.R;
import com.dwin.h5.app.ui.BaseActivity;
import com.dwin.h5.app.ui.pages.airkiss.AirKissEncoder;
import com.dwin.h5.app.ui.pages.airkiss.DeviceUtils;
import com.dwin.h5.app.utils.MobileUtil;
import com.dwin.h5.app.utils.ToastUtil;
import com.dwin.h5.app.views.dialogs.ConfigWifiDialogV2;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.List;

import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * 给硬件设备配置网络 UI2.0 2019.11.27
 * AirKiss 配网页面，原生Native实现
 */
@SuppressLint("NewApi")
public class ConfigureNetAirKissActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "ConfigureNetActivity";
    private static final int GPS_REQUEST_CODE = 456; // 打开GPS的请求码
    private static final int WIFI_REQUEST_CODE = 457; // wifi 判断修改的请求码

    private TextView tvTitle;
    private ImageView iv_config_wifi;
    private RelativeLayout rl_body_2config, rl_body_configing, rl_body_failed;
    private ImageView ivRotateLoading; //
    private Button btn_start_config;

    //--------------设备配网参数----------------
    private String mCurrentSSID;
    private String mWifiPassword;

    //------------------------------------------
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_configure_net);
        initViews();

        if (!MobileUtil.isGpsOpen(this)) {
            new AlertDialog.Builder(this)
                    .setTitle(R.string.tips)
                    .setMessage(R.string.distribution_open_gps) // 拒绝, 退出应用
                    .setNegativeButton(R.string.cancel,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    finish();
                                }
                            })
                    .setPositiveButton(R.string.confirm,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) { //跳转GPS设置界面
                                    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                    startActivityForResult(intent, GPS_REQUEST_CODE);
                                }
                            }).setCancelable(false).show();
        }
    }

    //检查位置权限
    public boolean checkPermission(Activity context) {
        //9.0以前版本获取wifi ssid不用申请此权限
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            return true;
        }
        int result = context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
        if (result == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        String[] permission = {Manifest.permission.ACCESS_COARSE_LOCATION};
        context.requestPermissions(permission, 1001);
        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (isWifi5G(this)) { // 判断wifi是否是5g判断
            new AlertDialog.Builder(this).setTitle(R.string.tips)
                    .setMessage(R.string.require_wifi_mode_24) // 拒绝, 退出应用
                    .setPositiveButton(R.string.set_wifi_24g,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) { // 跳转WIFI设置界面
                                    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
                                    startActivityForResult(intent, WIFI_REQUEST_CODE);
                                }
                            }).setCancelable(false).show();
        }
        if (checkPermission(this)) {
            mCurrentSSID = DeviceUtils.getSSID(this);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (sendSubs != null && !sendSubs.isUnsubscribed()) {
            sendSubs.unsubscribe();
            sendSubs = null;
        }
        if (receiveSubs != null && !receiveSubs.isUnsubscribed()) {
            receiveSubs.unsubscribe();
            receiveSubs = null;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (sendSubs != null && !sendSubs.isUnsubscribed()) {
            sendSubs.unsubscribe();
            sendSubs = null;
        }
        if (receiveSubs != null && !receiveSubs.isUnsubscribed()) {
            receiveSubs.unsubscribe();
            receiveSubs = null;
        }
        ivRotateLoading.clearAnimation();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == GPS_REQUEST_CODE && resultCode == RESULT_OK) {
            doCoarseLocation();
        }
    }

    @Override
    public void doCoarseLocation() {
        if (DeviceUtils.isWifi(this)) {
            mCurrentSSID = DeviceUtils.getSSID(this);
        }
    }

    @Override
    protected void initViews() {
        Button btnLeft = findViewById(R.id.btn_header_left);
        btnLeft.setVisibility(View.VISIBLE);
        btnLeft.setOnClickListener(this);
        tvTitle = findViewById(R.id.tv_header_title);
        tvTitle.setText(R.string.wifi_configuration);

        iv_config_wifi = findViewById(R.id.iv_config_wifi);
        iv_config_wifi.setBackgroundResource(R.drawable.anim_config_net);
        AnimationDrawable ad = (AnimationDrawable) iv_config_wifi.getBackground();
        ad.start();

        rl_body_2config = findView(R.id.rl_body_2config);
        rl_body_configing = findView(R.id.rl_body_configing);
        rl_body_failed = findView(R.id.rl_body_failed);

        btn_start_config = findViewById(R.id.btn_start_config);
        btn_start_config.setOnClickListener(this);
        findViewById(R.id.tv_config_info).setOnClickListener(this);

        ivRotateLoading = findView(R.id.iv_config_anim);
        ivRotateLoading.setBackgroundResource(R.drawable.anim_configing_net);
        AnimationDrawable adLoading = (AnimationDrawable) ivRotateLoading.getBackground();
        adLoading.start();
        findViewById(R.id.btn_config_again).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_header_left:
                finish();
                break;

            case R.id.tv_config_info:
                break;

            case R.id.btn_start_config: // 开始配置网络
                if (!isWifiConnect()) {
                    ToastUtil.toastShort(this, R.string.to_connect_wifi);
                    return;
                }
                String wifiPwd = logMessage.getString("wifiPassword", ""); // 获取之前保存的wifi密码
                final ConfigWifiDialogV2 dialog = new ConfigWifiDialogV2(mContext, R.style.DialogTheme);
                dialog.setMyTitle(mCurrentSSID);
                dialog.setCancelable(false);
                dialog.setMyPwd(wifiPwd); // 设置wifi密码
                dialog.setDialogListener(new ConfigWifiDialogV2.MyDialogListener() {
                    @Override
                    public void onClickPositive(String name, String password) {
                        logMessage.edit().putString("wifiPassword", password).commit();
                        dialog.dismiss();
                        Log.d(TAG, "wifi name: " + name + " password:" + password);
                        configureDeviceWifi(name, password);
                    }
                });
                dialog.show();
                break;

            case R.id.btn_config_again: // 重新配网
                doCoarseLocation();
                tvTitle.setText(R.string.wifi_configuration);
                rl_body_2config.setVisibility(View.VISIBLE);
                rl_body_configing.setVisibility(View.GONE);
                rl_body_failed.setVisibility(View.GONE);
                btn_start_config.performClick();
                break;
        }
    }

    private Subscription sendSubs, receiveSubs;
    private String macAddress = null; // 设备mac地址

    //------------配网流程------------------------------
    private void configureDeviceWifi(String name, final String password) {
        // 开始配网流程，显示动画
        tvTitle.setText(R.string.device_in_distribution);
        rl_body_2config.setVisibility(View.GONE);
        rl_body_configing.setVisibility(View.VISIBLE);
        rl_body_failed.setVisibility(View.GONE);

        if (!TextUtils.isEmpty(name)) {
            final AirKissEncoder airKissEncoder = new AirKissEncoder(name, password);
            sendSubs = Observable.create(new Observable.OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    sendPackage(airKissEncoder, subscriber);
                }
            }).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<String>() {
                        @Override
                        public void onCompleted() {
                        }

                        @Override
                        public void onError(Throwable e) { // 连接失败
//                            tvTitle.setText("搜索并连接设备");
//                            rl_body_2config.setVisibility(View.GONE);
//                            rl_body_configing.setVisibility(View.GONE);
//                            rl_body_failed.setVisibility(View.VISIBLE);
                        }

                        @Override
                        public void onNext(String string) { // 连接:onNext
//                            Toast.makeText(mContext, R.string.esp_esptouch_result_over, Toast.LENGTH_LONG).show();
//                            tvTitle.setText("WIFI配置");
//                            rl_body_2config.setVisibility(View.VISIBLE);
//                            rl_body_configing.setVisibility(View.GONE);
//                            rl_body_failed.setVisibility(View.GONE);
                        }
                    });

            // 接收设备返回的udp 数据包
            receiveSubs = Observable.create(new Observable.OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    receivePackage(airKissEncoder, subscriber);
                }
            }).subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<String>() {
                        @Override
                        public void onStart() {
                            super.onStart();
                        }

                        @Override
                        public void onCompleted() {
                        }

                        @Override
                        public void onError(Throwable e) {
                            Toast.makeText(mContext, R.string.esp_esptouch_result_over, Toast.LENGTH_LONG).show();
                            tvTitle.setText(R.string.wifi_configuration);
                            rl_body_2config.setVisibility(View.VISIBLE);
                            rl_body_configing.setVisibility(View.GONE);
                            rl_body_failed.setVisibility(View.GONE);
                        }

                        @Override
                        public void onNext(String s) {
                            if ("success".equals(s)) {
                                Toast.makeText(mContext, R.string.esp_esptouch_result_suc, Toast.LENGTH_LONG).show();
                                Intent data = new Intent();
                                data.putExtra("device_bssid", macAddress);
                                setResult(RESULT_OK, data);
                                finish();
                            }
                        }
                    });

        } else {
            Toast.makeText(this, R.string.esp_esptouch_connection_hint, Toast.LENGTH_LONG).show();
        }
    }

    // 接收udp包
    private void receivePackage(AirKissEncoder airKissEncoder, Subscriber subscriber) {
        byte[] buffer = new byte[15000];
        DatagramSocket udpServerSocket = null;
        try {
            udpServerSocket = new DatagramSocket(10001); // 10000
            udpServerSocket.setSoTimeout(1000 * 60);//设置超时时间
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            while (true) {
                udpServerSocket.receive(packet);
                byte[] receivedData = packet.getData();
                Log.d(TAG, "receivedData:" + new String(receivedData));
                String receiveStr = new String(packet.getData(), 0, packet.getLength());
                String[] strArr = receiveStr.split("=");
                if (strArr != null && strArr.length >= 2) {
                    macAddress = strArr[0];
                    subscriber.onNext("success");
                    break;
                }
            }
            subscriber.onCompleted();
        } catch (SocketException e) {
            subscriber.onError(e);
            e.printStackTrace();
        } catch (IOException e) {
            subscriber.onError(e);
            e.printStackTrace();
        } finally {
            udpServerSocket.close();
            udpServerSocket.disconnect();
        }
    }


    private void sendPackage(AirKissEncoder airKissEncoder, Subscriber subscriber) {
        byte[] DUMMY_DATA = new byte[1500];
        DatagramSocket sendSocket = null;
        try {
            sendSocket = new DatagramSocket();
            sendSocket.setBroadcast(true);
            int[] encoded_data = airKissEncoder.getEncodedData();
            for (int encoded_datum : encoded_data) {
                DatagramPacket pkg = new DatagramPacket(DUMMY_DATA,
                        encoded_datum,
                        InetAddress.getByName("255.255.255.255"),
                        10000);
                sendSocket.send(pkg);
                Thread.sleep(4);
            }
            subscriber.onCompleted();
        } catch (Exception e) {
            subscriber.onError(e);
            e.printStackTrace();
        } finally {
            sendSocket.close();
            sendSocket.disconnect();
        }
    }


    /**
     * 判断连接的wifi是否是5G 频段的
     *
     * @param context
     * @return
     */
    public static boolean isWifi5G(Context context) {
        int freq = 0;
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            freq = wifiInfo.getFrequency();
        } else {
            String ssid = wifiInfo.getSSID();
            if (ssid != null && ssid.length() > 2) {
                String ssidTemp = ssid.substring(1, ssid.length() - 1);
                List<ScanResult> scanResults = wifiManager.getScanResults();
                for (ScanResult scanResult : scanResults) {
                    if (scanResult.SSID.equals(ssidTemp)) {
                        freq = scanResult.frequency;
                        break;
                    }
                }
            }
        }
        return freq > 4900 && freq < 5900;
    }

}
